use IO::Socket;
use Net::TiVo;
use Cache::FileCache;
use XML::Simple;
use Data::Dumper;

my %local_files;	
my %convert_files;
my $nowait_flag;
my $beacon_message;
my $tivo_host;
my $download_flag;

my $config = XMLin();
my $file_wait=$config->{file_wait};
my $wait=$config->{wait};
my $MAK=$config->{MAK};
my $directory=$config->{directory};
my $download_dir=$config->{download_dir};


#create cache object
my $cache = Cache::FileCache->new({
	namespace          => 'TiVo',
	default_expires_in => $wait/2,}
);

#create socket to listen for the tivo beacon packets
my $socket=IO::Socket::INET->new(LocalPort=>2190,Proto => 'udp')
  or die "cannot create socket - $!";

#continuously receive beacon packets until one is received with platform=tcd, indicating a tivo system
#this will ignore beacons from pytivo or any other tivo apps on your network
while (!$found_tivo){
	$socket->recv($beacon_message,1024);
	if ($beacon_message=~m/platform=(tcd)/){
		$found_tivo=1;
		($port, $ipaddr)=sockaddr_in($socket->peername);
		$tivo_host= inet_ntoa($ipaddr);
	}
}
#create net::tivo object to interface with system
my $tivo = Net::TiVo->new(
	host => $tivo_host, 
	mac  => $MAK,
	cache => $cache,
);


while (1){
	$nowait_flag=0;		#used to start another iteration of the loop immediately if any download actions were taken
	%convert_files = ();	#hash for local files that are mpg and thus have already been converted
	%local_files= ();		#hash for all local files, mpg and tivo
	%meta_files= ();		#hash for local metadata files
	%files_not_ready;		#hash for files that have not yet been downloaded because they are not ready
	#open local directory and look for files
	opendir DH, $directory or die "Cannot open directory";
	foreach $file (readdir DH) {
		#need to replace any special characters with "="
		$file=~s#(\\|/|:|\*|\?|\"|<|>|\|)#=#g;
		#Check for all mpg or tivo files.
		if ($file=~m/(.*)\.(mpg|tivo)$/i){
			$local_files{$1}=1;
		}
		#check for all tivo files that need conversion
		if ($file=~m/(.*)\.tivo/i){
			$convert_files{$file}=$1;
		}
		#check for metadata files
		if ($file=~m/(.*)\.(mpg|tivo)\.txt/i){
			$meta_files{$1}=1;
		}
	}
	closedir DH;
	
	#loop through the files needing conversion
	while (($key, $value) = each %convert_files) {
		#setup decode command and run
		$command="tivodecode -m ".$MAK." -o \"$download_dir".$value.".mpg\" \"$download_dir".$key."\"";
		system($command);   #really should check results here....
		#setup command to delete original mpg after conversion
		$command = "del /Q \"".$download_dir.$key."\"";
		system($command);
	}
	
	#delete meta files that have no video files, keeping directory clean
	while (($key, $value) = each %meta_files) {
		if (!($local_files{$key})){
			$command = "del /Q \"".$download_dir.$key.".mpg.txt\"";
			system($command);
		}
	}
	for my $folder ($tivo->folders()) {
		for my $show ($folder->shows()) {
			my $current_file=$show->name()."-".$show->episode()."-".$show->capture_date();
			$current_file=~s#(\\|/|:|\*|\?|\"|<|>|\|)#=#g;
#			$url=$show->url();
#			$episode=$show->episode;
#			$name=$show->name;
#			$description=$show->description;
#			$seriesid=$show->series_id;
			if ($show->in_progress=~/yes/i){
				print "not ready for download\n";
				$download_flag=0;
			}
			else {
				print "ready for download\n";
				$download_flag=1;
			}
			if ($download_flag){ 
				if (exists $local_files{$current_file}){
					#this gets the metadata from the tivo itself..it might be better to get it from the tivo file
					if (!(exists $meta_files{$file})){
						$meta_name=$download_dir.$current_file.".mpg.txt";
						open FILE, ">$meta_name" or die $!;;
						print FILE "seriesTitle : ",$show->name,"\n";
						print FILE "title : ",$show->name,"-",$show->episode,"\n";
						print FILE "description : ",$show->description,"\n";
						print FILE "seriesID : ",$show->series_id,"\n";
						close FILE;
					}
				}
				else {
					#set up curl command to download file.
					#have to use cookie command to allow authentication to work
					#might be able to do this directly with perl, but too lazy to figure it out just yet.
					$command = "curl -c cookie -u tivo:$MAK --digest -o \"".$download_dir.$current_file.".tivo\" \"".$show->url()."\"";
					system($command);
					$nowait_flag=1;
					$meta_name=$download_dir.$current_file.".mpg.txt";
					#this gets the metadata from the tivo itself..it might be better to get it from the tivo file
					open FILE, ">$meta_name" or die $!;;
					print FILE "seriesTitle : ",$show->name,"\n";
					print FILE "title : ",$show->name,"-",$show->episode,"\n";
					print FILE "description : ",$show->description,"\n";
					print FILE "seriesID : ",$show->series_id,"\n";
					close FILE;
				}
			}
		}
	}
	#runs next iteration of loop if a download has happened...no need to wait.
	if (! $nowait_flag) {
		print "\nWaiting $wait seconds for next cycle...\n";
		sleep($wait);
	}

}

